#include <iostream>
#include "miniutil/socketmultiplex.h"
#include "miniutil/threadpool.h"
#include "miniutil/mhttpclient.h"
#include "minitest/testcase.h"

using namespace miniutil::multinet;

class testmhttpclient: public testcase
{
public:

	class testpeer
	{
	public:
		httpclient hcli;
		std::string checkurl;
		std::string prestus;

		char buf[1024];
		int haveread;

		testpeer(SocketMulplexService* pss)
			:hcli(pss)
		{
		}

		void check(std::string urlin)
		{
			hcli.do_GET(urlin);
			prestus = "prep";
			haveread = 0;
			checkurl = urlin;
		}

		int working()
		{
			std::string stus;
			hcli.working();
			int ret = hcli.get_status();
			if(ret == httpclient::STUS_FIN || ret == httpclient::STUS_FAIL)
				return 1;
			switch(ret)
			{
			case httpclient::STUS_CONNETING:
				stus = "connecting...";
				break;
			case httpclient::STUS_CONNECTED:
				stus = "connected...";
				break;
			case httpclient::STUS_REQDONE:
				stus = "req sent...";
				break;
			case httpclient::STUS_RESP_HEADER:
				stus = "have receive header...";
				ret = hcli.get_resp_content(buf, sizeof(buf));
				if(ret > 0)
				{
					haveread += ret;
					//std::cout<<checkurl<<" reading "<<haveread<<std::endl;
				}
				break;
			case httpclient::STUS_FIN:
				stus = "receive content finish";
				std::cout<<checkurl<<" total read "<<haveread<<std::endl;
				break;
			case httpclient::STUS_FAIL:
				stus = "connect fail";
				break;
			}
			if(prestus != stus)
			{
				std::cout<<checkurl<<" "<<stus<<std::endl;
				prestus = stus;
			}
			return 0;
		}
	};

	void test2()
	{
		SocketMulplexService_Select select_service;
		select_service.start_service();
		testpeer a(&select_service);
		testpeer b(&select_service);
		testpeer c(&select_service);

		std::vector<testpeer*> peers;
		peers.push_back(&a);
		peers.push_back(&b);
		peers.push_back(&c);

		a.check("www.sohu.com");
		b.check("www.sina.com");
		c.check("www.163.com");
		std::vector<testpeer*>::iterator iter_vt;
		while(true)
		{
			if(peers.size() == 0)
				break;
			for(iter_vt=peers.begin(); iter_vt != peers.end();)
			{
				int ret = (*iter_vt)->working();
				if(ret == 1)
				{
					iter_vt = peers.erase(iter_vt);
				}
				else
					iter_vt ++;
			}
			miniutil::thread::sleep(1);
		}

		select_service.stop_service();
	}

	void test1(std::string urlin)
	{
		std::cout<<"check :"<<urlin<<std::endl;
		SocketMulplexService_Select select_service;
		select_service.start_service();

		httpclient hcli(&select_service);
		hcli.do_GET(urlin);
		std::string prestus = "prep";
		std::string stus;

		char buf[1024];
		int haveread = 0;
		while(true)
		{
			hcli.working();
			int ret = hcli.get_status();
			switch(ret)
			{
			case httpclient::STUS_CONNETING:
				stus = "connecting...";
				break;
			case httpclient::STUS_CONNECTED:
				stus = "connected...";
				break;
			case httpclient::STUS_REQDONE:
				stus = "req sent...";
				break;
			case httpclient::STUS_RESP_HEADER:
				stus = "have receive header...";
				while(true)
				{
					int respcontret = hcli.get_resp_content(buf, sizeof(buf));
					if(respcontret > 0)
					{
						haveread += respcontret;
						std::cout<<"reading "<<haveread<<std::endl;
					}
					else
						break;
				}
				break;
			case httpclient::STUS_FIN:
				stus = "receive content finish";
				while(true)
				{
					int respcontret = hcli.get_resp_content(buf, sizeof(buf));
					if(respcontret > 0)
					{
						haveread += respcontret;
						std::cout<<"reading "<<haveread<<std::endl;
					}
					else
						break;
				}
				std::cout<<"total read "<<haveread<<std::endl;
				break;
			case httpclient::STUS_FAIL:
				stus = "connect fail";
				while(true)
				{
					int respcontret = hcli.get_resp_content(buf, sizeof(buf));
					if(respcontret > 0)
					{
						haveread += respcontret;
						std::cout<<"reading "<<haveread<<std::endl;
					}
					else
						break;
				}
				break;
			case httpclient::STUS_TIMEOUT:
				stus = "connect time out";
				break;
			}
			if(prestus != stus)
			{
				std::cout<<stus<<std::endl;
				prestus = stus;
			}
			if(ret == httpclient::STUS_FIN || ret == httpclient::STUS_FAIL)
				break;
			miniutil::thread::sleep(1);
		}
		select_service.stop_service();
	}

	virtual void test()
	{
#ifdef WIN32
		{WSADATA data; WSAStartup(MAKEWORD(2,2), &data);}
#endif
		//test1("www.163.com");
		//test1("www.sina.com");
		//test1("www.sohu.com");
		//test2();
		test1("http://btfans.3322.org:8000/announce?info_hash=%F6%C2%D2%F74%C9%C0%7F%83%D5%07%21%A3%28%116%F0%85X%8A&peer_id=%2DUT1720%2Dc0a801ad6c22&port=8812&uploaded=1024&downloaded=1024&left=1024&compact=0&event=started&numwant=100&ip=192.168.1.173&localip=192.168.1.173&key=29025671041242291117");
	}


};

testcase * testmhttp1 = new testmhttpclient();
